package org.example.zpqy.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.zpqy.bean.AppleOne;
import org.example.zpqy.bean.AppleGround;
import org.example.zpqy.repository.AppleOneRepository;
import org.example.zpqy.repository.AppleGroundRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Service
public class AppleMaturityService {

    @Autowired
    private AppleOneRepository appleOneRepository;

    @Autowired
    private AppleGroundRepository appleGroundRepository;

    private final String AI_API_URL = "https://open.bigmodel.cn/api/paas/v4/chat/completions";
    private final String AI_API_KEY = "0bd7298d801d4f26b6a622aa262af4b3.AyYdND8tk1HpcLMn";  // 你自己的 Key

    private final String WEATHER_API_URL = "https://restapi.amap.com/v3/weather/weatherInfo";
    private final String WEATHER_API_KEY = "476fc756852a8caa003633f8074ffff5"; // 你自己的 Key

    private final ObjectMapper objectMapper = new ObjectMapper();

    public List<Map<String, Object>> getMaturityInfo(String cropName, String cityCode) {
        // 1. 获取果树数据
        List<AppleOne> treeData = appleOneRepository.findAll();

        // 2. 获取果园环境数据
        List<AppleGround> groundData = appleGroundRepository.findAll();

        // 3. 获取天气信息
        RestTemplate restTemplate = new RestTemplate();
        String weatherUrl = WEATHER_API_URL + "?city=" + cityCode + "&key=" + WEATHER_API_KEY + "&extensions=all";
        String weatherInfo = restTemplate.getForObject(weatherUrl, String.class);

        // 4. 构造提示词（更简洁，只要3个结果）
        StringBuilder sb = new StringBuilder();
        sb.append("作物：").append(cropName).append("\n\n");
        sb.append("以下是果树监测数据（氮/磷/钾/水分）：\n");

        for (int i = 1; i <= 10; i++) {
            String nitrogen = getValueByAttribute(treeData, "氮", i);
            String phosphorus = getValueByAttribute(treeData, "磷", i);
            String potassium = getValueByAttribute(treeData, "钾", i);
            String moisture = getValueByAttribute(treeData, "水分", i);

            sb.append("果树编号:").append(i).append(" -> ")
                    .append("氮=").append(nitrogen).append(", ")
                    .append("磷=").append(phosphorus).append(", ")
                    .append("钾=").append(potassium).append(", ")
                    .append("水分=").append(moisture).append("\n");
        }

        sb.append("\n果园环境数据：").append(groundData.toString());
        sb.append("\n天气信息：").append(weatherInfo);

        // ✅ 要求 AI 只返回三项
        sb.append("\n\n请根据果树生长周期、环境和天气，输出 JSON 数组，格式如下：\n")
                .append("[\n")
                .append("  {\n")
                .append("    \"treeId\": \"果树编号\",\n")
                .append("    \"maturity\": \"成熟度百分比(0-100)\",\n")
                .append("    \"stage\": \"当前生长阶段(如萌芽期/花期/结果期等)\",\n")
                .append("    \"prediction\": \"预计成熟时间(如预计5天后成熟)\"\n")
                .append("  }\n")
                .append("]\n")
                .append("注意：\n")
                .append("1. 只输出纯 JSON 数组，不要包含额外文字或 markdown。\n")
                .append("2. 每棵果树都必须包含 treeId、maturity、stage、prediction 三个字段。\n");

        // 5. 构造请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "glm-4-flash");
        requestBody.put("messages", List.of(
                Map.of("role", "user", "content", sb.toString())
        ));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(AI_API_KEY);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

        // 6. 调用 AI 接口
        ResponseEntity<Map> response = restTemplate.postForEntity(AI_API_URL, request, Map.class);

        // 7. 解析返回结果
        List<Map<String, Object>> resultList = new ArrayList<>();
        Map<String, Object> resp = response.getBody();

        if (resp != null && resp.containsKey("choices")) {
            List choices = (List) resp.get("choices");
            if (!choices.isEmpty()) {
                Map choice = (Map) choices.get(0);
                Map message = (Map) choice.get("message");
                String aiContent = message.get("content").toString().trim();

                // 去掉 ```json ``` 包裹
                aiContent = aiContent.replaceAll("```json", "").replaceAll("```", "").trim();

                try {
                    JsonNode root = objectMapper.readTree(aiContent);
                    if (root.isArray()) {
                        for (JsonNode node : root) {
                            Map<String, Object> item = new HashMap<>();
                            item.put("treeId", node.path("treeId").asText("未知编号"));
                            item.put("maturity", node.path("maturity").asText("0"));
                            item.put("stage", node.path("stage").asText("未知阶段"));
                            item.put("prediction", node.path("prediction").asText("未知"));
                            resultList.add(item);
                        }
                    }
                } catch (Exception e) {
                    Map<String, Object> error = new HashMap<>();
                    error.put("treeId", "0");
                    error.put("maturity", "0");
                    error.put("stage", "AI输出解析错误");
                    error.put("prediction", aiContent);
                    resultList.add(error);
                }
            }
        }

        return resultList;
    }

    // 工具方法：根据 attribute 找值
    private String getValueByAttribute(List<AppleOne> data, String attribute, int treeIndex) {
        for (AppleOne row : data) {
            if (row.getAttribute().contains(attribute)) {
                Integer val = row.getApptreeValue(treeIndex);
                return val == null ? "无数据" : val.toString();
            }
        }
        return "无数据";
    }
}
